/**
 * 
 */
package gui.trainer;

/**
 * @author Louis
 *
 */
/**
 * 
 */

import gui.GUIMaster;
import gui.InputPanel;
import handwritten.character.CharacterCollection;
import handwritten.character.CharacterCollectionManager;
import handwritten.character.RawHandWrittenCharacter;
import handwritten.gesture.HandInputManager;
import handwritten.grid.Trainning;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import recognition.engine.RecognitionEngine;
import recognition.engine.metric.BasicMetric;
import recognition.engine.nn.NNRecognizer;
import recognition.output.PredictedCharacter;
import recognition.preprocessor.CreateMGInpute;
import recognition.preprocessor.LengthSetter;
import recognition.preprocessor.Preprocessor;
import recognition.preprocessor.RawPreprocessor;
import recognition.preprocessor.RemoveTwoFollowingSamePoint;
import recognition.preprocessor.Resampling;
import recognition.preprocessor.Smoother;
import recognition.preprocessor.setCOMPosition;
import auth.User;
import utility.io.HWCharacterIO;
import utility.io.HWCharacterIOFactory;
import utility.math.Vector2D;

/**
 * @author tioz
 * The density should be greater than one
 */

public class TrainerFrame extends JFrame implements GUIMaster{

	
	private static TrainerFrame instance;
	private User user = new User("wrere");
	
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private TrainerInputPanel inputPanel;
	private JPanel menuPanel;
	
	//testpurpose
	private final RecognitionEngine engine;
	private RecognitionEngine testEngine;
	
	
	
	/**
	 * @throws HeadlessException
	 */
	private TrainerFrame() throws HeadlessException {
		super("TrueMath");
		//FIXME
		//test purpose
		engine = new RecognitionEngine(new RawPreprocessor(), 10);
		engine.addRecognizer(new NNRecognizer(1));

		
		Preprocessor tmp1,tmp2;
		
		Preprocessor prepros = new RemoveTwoFollowingSamePoint();
		
		tmp1 = new Smoother();
		prepros.addChild(tmp1);
		
		tmp2 = new RawPreprocessor();
		tmp1.addChild(tmp2);
		
		tmp1 = new Resampling(1);
		tmp2.addChild(tmp1);
		
		tmp2 = new LengthSetter(200);
		tmp1.addChild(tmp2);

		tmp1 = new setCOMPosition(new Vector2D(200,200));
		tmp2.addChild(tmp1);
		
		tmp2 = new CreateMGInpute();
		tmp1.addChild(tmp2);
				
		testEngine = new  RecognitionEngine(prepros,10);
    	testEngine.addRecognizer(new BasicMetric(testEngine,1));
    
    	
    	
    	ImageIcon img = new ImageIcon("picture/icon.png");
    	setIconImage(img.getImage());
    
		//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(200,200);
		
		inputPanel = new TrainerInputPanel(this);
		menuPanel= new JPanel();
				
		getContentPane().setLayout(new BorderLayout());
		getContentPane().add(inputPanel, BorderLayout.CENTER);
		getContentPane().add(menuPanel,BorderLayout.SOUTH);
		
		this.addWindowListener(new WindowAdapter(){

			
			@Override
			public void windowClosing(WindowEvent e) {
				//TODO Here we should save the collections
				System.exit(0);
			}
			
		});
		
		createMenu();
		
		setResizable(false);
		
		setVisible(true);
	}
	
	public void createMenu(){
		JButton clear = new JButton("clear");
		JButton next  = new JButton("next");
		JButton exit  = new JButton("Save and exit");
		JButton recognize = new JButton("recognize");
	
		
		menuPanel.setLayout(new GridLayout(3,1));
		
		JPanel top = new JPanel();
		top.setLayout(new GridLayout(1,2));
		top.add(clear);
		top.add(next);
		menuPanel.add(top);
		menuPanel.add(recognize);
		menuPanel.add(exit);
		
		recognize.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent arg0) {
				//TODO here we should save the object
				
				//ArrayList<PredictedCharacter> prediction = engine.recognize(HandInputManager.getInstance().getHandWrittenCharacter());
				RawHandWrittenCharacter c = HandInputManager.getInstance().getHandWrittenCharacter();
				
				//ArrayList<PredictedCharacter> prediction = Engine.recognize(c);
										
				ArrayList<PredictedCharacter> prediction = testEngine.recognize(c);
				
				for(PredictedCharacter pc : prediction){
					System.out.println(pc.getId()+" : "+pc.getConfidence());
				}
				
				HandInputManager.getInstance().clearGesture();
				repaint();
			}
		});
		
		exit.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent arg0) {
				//TODO here we should save the object
				
				HWCharacterIO io = HWCharacterIOFactory.getInstance().getHWCharacterIO("XML");
				try {
					io.saveCollections(user);
				} catch (IOException e) {
					System.out.print("bad files system bad");
					e.printStackTrace();
				}
				
				System.exit(0);
			}
		});
		
		
		clear.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent arg0) {
				HandInputManager.getInstance().clearGesture();
				repaint();
			}
		});
		
		next.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent arg0) {
				RawHandWrittenCharacter hwChar = HandInputManager.getInstance().getHandWrittenCharacter();
				
				@SuppressWarnings("unchecked") //Should be safe is the Manager is well done
				CharacterCollection<RawHandWrittenCharacter> collection = (CharacterCollection<RawHandWrittenCharacter>) CharacterCollectionManager.getInstance().getCollection(user,"RAW",RawHandWrittenCharacter.class); 
				
				collection.addSample(hwChar);				
				HandInputManager.getInstance().clearGesture();
				Trainning training = HandInputManager.getInstance().getTrainning();
				training.setExpectedChar(new int[]{(int)(Math.random()*(training.charCollectionSize()-1))});
				repaint();
				
			}
		});
		
	}


	public static TrainerFrame getInstance(){
		if(instance != null)
			return instance;
		instance = new TrainerFrame();
		return instance; 
	}
	

	public void paint(){
		inputPanel.repaint();
	}
	
	
	
	public InputPanel getInputPanel() {
		return inputPanel;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
					
		SwingUtilities.invokeLater(new Runnable(){
			public void run(){
				HWCharacterIO io = HWCharacterIOFactory.getInstance().getHWCharacterIO("XML");
				try {
					io.loadDataBase();
				} catch (IOException e) {
					System.out.print("oupps mal programmer io exeption");
					e.printStackTrace();
				}
				
				System.out.println("Collection loaded");
				for(User user : CharacterCollectionManager.getInstance().getUsers()){
					ArrayList<CharacterCollection<?>> cols = CharacterCollectionManager.getInstance().getCollections(user);
					for(CharacterCollection<?> col : cols){
						System.out.println("Type : "+col.getType().getCanonicalName() + " CollecType : "+ col.getCollecType());
						Enumeration<String> enume = col.keys();
						//System.out.println(enume.hasMoreElements());
						while(enume.hasMoreElements()){
							String id = enume.nextElement();
							System.out.println(id+" "+col.size(id));
						}
					}
				}
				TrainerFrame.getInstance();
			}
		});

	}
	
	
}


